﻿using System.Linq;
using Basmus.Conel;

using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;

namespace Basmus.Tests
{
    [TestClass()]
    public class EntityBinderTest
    {
        private TestContext testContextInstance;

        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Дополнительные атрибуты теста
        // 
        //При написании тестов можно использовать следующие дополнительные атрибуты:
        //
        //ClassInitialize используется для выполнения кода до запуска первого теста в классе
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //ClassCleanup используется для выполнения кода после завершения работы всех тестов в классе
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //TestInitialize используется для выполнения кода перед запуском каждого теста
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //TestCleanup используется для выполнения кода после завершения каждого теста
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion

        [TestMethod()]
        public void ValueTypeEntityBindingTest()
        {
            //Arrage
            var elementTypes = TypeHelper.ValueTypes();
            var binder = new EntityBinder();

            //Arrage & Act & Assert
            foreach (var elementType in elementTypes)
            {
                //Arrange
                var expectedBindingType = typeof(ValueTypeEntityBinding<>).MakeGenericType(elementType);

                //Act
                var binding = binder.Bind(elementType);

                //Assert
                Assert.IsNotNull(binding);
                Assert.IsInstanceOfType(binding, expectedBindingType);

                //Act
                binding = binder.Bind(elementType, elementType);

                //Assert
                Assert.IsNotNull(binding);
                Assert.IsInstanceOfType(binding, expectedBindingType);
            }
        }

        [TestMethod()]
        public void StringBindingTest()
        {
            //Arrage
            var elementTypes = TypeHelper.ReferenceTypes();
            var binder = new EntityBinder();

            //Arrage & Act & Assert
            foreach (var elementType in elementTypes)
            {
                //Arrange
                var expectedBindingType = typeof (StringBinding);

                //Act
                var binding = binder.Bind(elementType);

                //Assert
                Assert.IsNotNull(binding);
                Assert.IsInstanceOfType(binding, expectedBindingType);

                //Act
                binding = binder.Bind(elementType, elementType);

                //Assert
                Assert.IsNotNull(binding);
                Assert.IsInstanceOfType(binding, expectedBindingType);
            }
        }

        [TestMethod()]
        public void NullTest()
        {
            //Arrage
            var containerTypes = TypeHelper.EveryPossibleContainerType().Except(TypeHelper.EveryPossibleElementTypes());
            var binder = new EntityBinder();

            //Act & Assert
            foreach (var containerType in containerTypes)
            {
                //Act
                var binding = binder.Bind(containerType);

                //Assert
                Assert.IsNull(binding);
            }
        }
        [TestMethod()]
        public void NullWithElementTypeTest()
        {
            //Arrage & Act & Assert
            foreach (var elementType in TypeHelper.EveryPossibleElementTypes())
            {
                foreach (var containerType in TypeHelper.EveryPossibleContainerType().Where(x => x != elementType))
                {
                    //Arrange
                    var binder = new EntityBinder();

                    //Act
                    var binding = binder.Bind(containerType, elementType);

                    //Assert
                    Assert.IsNull(binding);
                }
            }
        }
    }
}
